package com.informa.java.util;

import static java.util.Calendar.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class CalendarBuilder {

	public static final int SEVEN_DAYS_IN_A_WEEK = 7;
	private int daysOffset = 0;
	private Calendar calendar = new GregorianCalendar();
	
	public Calendar build() {
		calendar.add(DAY_OF_YEAR, daysOffset);
		return calendar;
	}

	public CalendarBuilder weeksAgo(int weeksAgo) {
		calendar.add(DAY_OF_YEAR, -weeksAgo * SEVEN_DAYS_IN_A_WEEK);
		return this;
	}

	public CalendarBuilder weeksAhead(int weeksAhead) {
		
		
		calendar.add(DAY_OF_YEAR, weeksAhead * SEVEN_DAYS_IN_A_WEEK);
		return this;
	}

	public CalendarBuilder daysAgo(int daysAgo) {
		calendar.add(DAY_OF_YEAR, -daysAgo);
		return this;
	}
	
	public CalendarBuilder daysAhead(int daysAhead) {
		calendar.add(DAY_OF_YEAR, daysAhead);
		return this;
	}

	public CalendarBuilder hoursAgo(int hoursAgo) {
		calendar.add(HOUR_OF_DAY, -hoursAgo);
		return this;
	}
	
	public CalendarBuilder hoursAhead(int hoursAhead) {
		calendar.add(HOUR_OF_DAY, hoursAhead);
		return this;
	}
	
	public CalendarBuilder minutesAgo(int minutesAgo) {
		calendar.add(MINUTE, -minutesAgo);
		return this;
	}
	
	public CalendarBuilder minutesAhead(int minutesAhead) {
		calendar.add(MINUTE, minutesAhead);
		return this;
	}
	
	public CalendarBuilder withTimeSetTo(Date date) {
		calendar.setTime(date);
		return this;
	}
	
	/**
	 * Set the time component of the given Calendar to midnight.  
	 * 
	 * This method doesn't use Calendar.clear() as it is unreliable. 
	 * @see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4414844 
	 * 
	 * @param calendar
	 * @return
	 */
	public CalendarBuilder withTimeSetToMidnight() {
		calendar.set(AM_PM, Calendar.AM);
		calendar.set(HOUR, 0);
		calendar.set(HOUR_OF_DAY, 0);
		calendar.set(MINUTE, 0);
		calendar.set(SECOND, 0);
		calendar.set(MILLISECOND, 0);
		return this;
	}

	public CalendarBuilder year(int year) {
		calendar.set(YEAR, year);
		return this;
	}

	public CalendarBuilder month(Month month) {
		calendar.set(MONTH, month.getIndex());
		return this;
	}

	public CalendarBuilder dayOfMonth(int dayOfMonth) {
		calendar.set(DAY_OF_MONTH, dayOfMonth);
		return this;
	}

	public Date buildDate() {
		return build().getTime();
	}

	public Long buildMillis() {
		return buildDate().getTime();
	}

	public CalendarBuilder hours(int hours) {
		calendar.set( HOUR, hours );
		return this;
	}
	
	public CalendarBuilder minutes(int minutes) {
		calendar.set( MINUTE, minutes );
		return this;
	}
	
	public CalendarBuilder seconds(int seconds) {
		calendar.set( SECOND, seconds );
		return this;
	}

}
